/**
 * Vue 3 装饰器实现
 * 用于增强电子病历审核系统的功能
 */

/**
 * 日志装饰器 - 记录方法调用
 * @param {string} prefix - 日志前缀
 */
export function Log(prefix = '') {
  return function (target, name, descriptor) {
    const method = descriptor.value;
    
    descriptor.value = function (...args) {
      console.log(`[LOG ${prefix}] 调用方法: ${name}`, ...args);
      const result = method.apply(this, args);
      console.log(`[LOG ${prefix}] 方法返回:`, result);
      return result;
    };
    
    return descriptor;
  };
}

/**
 * 错误处理装饰器 - 捕获并处理方法中的错误
 * @param {Function} handler - 错误处理函数
 */
export function ErrorHandler(handler) {
  return function (target, name, descriptor) {
    const method = descriptor.value;
    
    descriptor.value = async function (...args) {
      try {
        const result = await method.apply(this, args);
        return result;
      } catch (error) {
        if (handler) {
          handler.call(this, error);
        } else {
          console.error(`[ERROR] 方法 ${name} 发生错误:`, error);
        }
        throw error;
      }
    };
    
    return descriptor;
  };
}

/**
 * 权限检查装饰器 - 检查用户是否有权限执行方法
 * @param {string[]} permissions - 所需权限列表
 */
export function Permission(permissions = []) {
  return function (target, name, descriptor) {
    const method = descriptor.value;
    
    descriptor.value = function (...args) {
      // 检查用户权限
      const userPermissions = this.$store?.state?.user?.permissions || [];
      const hasPermission = permissions.every(perm => userPermissions.includes(perm));
      
      if (!hasPermission) {
        console.warn(`[PERMISSION] 用户缺少权限: ${permissions.join(', ')}`);
        throw new Error('权限不足');
      }
      
      return method.apply(this, args);
    };
    
    return descriptor;
  };
}

/**
 * 加载状态装饰器 - 在方法执行期间设置加载状态
 * @param {string} loadingProp - 加载状态属性名
 */
export function Loading(loadingProp = 'loading') {
  return function (target, name, descriptor) {
    const method = descriptor.value;
    
    descriptor.value = async function (...args) {
      // 设置加载状态
      if (this.hasOwnProperty(loadingProp)) {
        this[loadingProp] = true;
      }
      
      try {
        const result = await method.apply(this, args);
        return result;
      } finally {
        // 重置加载状态
        if (this.hasOwnProperty(loadingProp)) {
          this[loadingProp] = false;
        }
      }
    };
    
    return descriptor;
  };
}

/**
 * 缓存装饰器 - 缓存方法的返回值
 * @param {number} ttl - 缓存时间（毫秒）
 */
export function Cache(ttl = 60000) {
  const cache = new Map();
  
  return function (target, name, descriptor) {
    const method = descriptor.value;
    
    descriptor.value = function (...args) {
      const key = JSON.stringify(args);
      const cached = cache.get(key);
      
      if (cached && Date.now() - cached.timestamp < ttl) {
        console.log(`[CACHE] 返回缓存结果: ${name}`, cached.value);
        return cached.value;
      }
      
      const result = method.apply(this, args);
      cache.set(key, {
        value: result,
        timestamp: Date.now()
      });
      
      // 清理过期缓存
      for (const [k, v] of cache.entries()) {
        if (Date.now() - v.timestamp >= ttl) {
          cache.delete(k);
        }
      }
      
      return result;
    };
    
    return descriptor;
  };
}

/**
 * 限流装饰器 - 限制方法调用频率
 * @param {number} delay - 限制时间间隔（毫秒）
 */
export function Throttle(delay = 1000) {
  return function (target, name, descriptor) {
    const method = descriptor.value;
    let lastCall = 0;
    
    descriptor.value = function (...args) {
      const now = Date.now();
      if (now - lastCall < delay) {
        console.warn(`[THROTTLE] 方法调用被限制: ${name}`);
        return;
      }
      
      lastCall = now;
      return method.apply(this, args);
    };
    
    return descriptor;
  };
}

/**
 * 电子病历审核装饰器 - 专门用于病历审核功能的装饰器
 * @param {Object} options - 配置选项
 */
export function MedicalRecordAudit(options = {}) {
  const {
    validate = true,
    log = true,
    handleErrors = true
  } = options;
  
  return function (target, name, descriptor) {
    const method = descriptor.value;
    
    descriptor.value = async function (...args) {
      try {
        // 记录日志
        if (log) {
          console.log(`[MEDICAL_RECORD_AUDIT] 开始审核病历: ${name}`, ...args);
        }
        
        // 验证输入数据
        if (validate && args.length > 0) {
          const records = args[0];
          if (!Array.isArray(records)) {
            throw new Error('病历数据必须是数组格式');
          }
          
          if (records.length === 0) {
            throw new Error('病历数据不能为空');
          }
        }
        
        // 执行原方法
        const result = await method.apply(this, args);
        
        // 记录结果
        if (log) {
          console.log(`[MEDICAL_RECORD_AUDIT] 审核完成: ${name}`, result);
        }
        
        return result;
      } catch (error) {
        // 错误处理
        if (handleErrors) {
          console.error(`[MEDICAL_RECORD_AUDIT] 审核过程中发生错误:`, error);
          // 可以在这里添加更详细的错误处理逻辑
        }
        throw error;
      }
    };
    
    return descriptor;
  };
}